﻿using HardcoreGame.Common.Helpers;
using HardcoreGame.Content.Buffs;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Terraria;
using Terraria.Audio;
using Terraria.ID;
using Terraria.ModLoader;

namespace HardcoreGame.Content.Projectiles.Sets.Acid
{
    public class Miasma : ModProjectile
    {
        public bool[] StuckInSomething = new bool[2];
        public float[] StuckKillTimer = new float[2];
        internal int StuckIndex = -1;
        public float forceGravity = 1.081f;
        public float MiscTimer;
        private Texture2D tex;
        public ref float Mode => ref Projectile.ai[0];
        public ref float Time => ref Projectile.ai[1];
        internal Player Owner
        {
            get
            {
                Player player = Main.player[Projectile.owner];
                if (player.whoAmI != Main.myPlayer)
                {
                    return null;
                }
                return player;
            }
        }
        public override void SetDefaults()
        {
            Projectile.width = Projectile.height = 50;
            Projectile.DamageType = Mode == 0f ? DamageClass.Melee : DamageClass.Ranged;
            Projectile.timeLeft = 300;
            Projectile.tileCollide = Mode == 1f;
            Projectile.hostile = false;
            Projectile.friendly = true;
            Projectile.penetrate = -1;
            Projectile.usesLocalNPCImmunity = true;
            Projectile.localNPCHitCooldown = -1;
            Projectile.Opacity = 0f;
        }
        public override void AI()
        {
            float num = Mode;
            if (num != 0f)
            {
                if (num == 1f)
                {
                    ThrownAI();
                }
            }
            else
            {
                HeldAI();
            }
            HandleMisc();
        }
        private void HandleMisc()
        {
            float num2;
            if (StuckInSomething[0])
            {
                float[] stuckKillTimer = StuckKillTimer;
                int num = 1;
                num2 = stuckKillTimer[num] + 1f;
                stuckKillTimer[num] = num2;
                if (num2 >= 500f)
                {
                    Projectile.Kill();
                }
            }
            if (StuckInSomething[1])
            {
                float[] stuckKillTimer2 = StuckKillTimer;
                int num3 = 1;
                num2 = stuckKillTimer2[num3] + 1f;
                stuckKillTimer2[num3] = num2;
                if (num2 >= 180f)
                {
                    Projectile.Kill();
                }
                Projectile.Opacity = MathHelper.Lerp(Projectile.Opacity, 0f, StuckKillTimer[1] / 60f / 3f);
            }
            Projectile.DamageType = Mode == 0f ? DamageClass.Melee : DamageClass.Ranged;
            Projectile.tileCollide = Mode == 1f;
            if (MiscTimer == 0f)
            {
                SoundStyle dd2_MonkStaffSwing = SoundID.DD2_MonkStaffSwing;
                dd2_MonkStaffSwing.Pitch = 0.12f;
                SoundEngine.PlaySound(dd2_MonkStaffSwing, new Vector2?(Projectile.Center), null);
            }
            num2 = MiscTimer + 1f;
            MiscTimer = num2;
            if (num2 < 30f)
            {
                Projectile.Opacity = MathHelper.Lerp(Projectile.Opacity, 1f, 0.07f);
            }
        }
        private void ThrownAI()
        {
            Projectile.timeLeft++;
            if (StuckInSomething[0] && StuckIndex != -1)
            {
                NPC npc = Main.npc[StuckIndex];
                if (npc != null && npc.CanBeChasedBy(Projectile, false))
                {
                    Projectile.Center = npc.Center - Projectile.velocity * 2f;
                    Projectile.gfxOffY = npc.gfxOffY;
                    ref float time = ref Time;
                    float num = time + 1f;
                    time = num;
                    if (num % 39f == 0f)
                    {
                        npc.SimpleStrikeNPC(Projectile.damage / 3, 0, false, 0f, DamageClass.Ranged, false, 0f, false);
                    }
                }
                else
                {
                    Projectile.Kill();
                }
            }
            if (!StuckInSomething[0] && !StuckInSomething[1])
            {
                ref float time2 = ref Time;
                float num = time2 + 1f;
                time2 = num;
                if (num < 10f)
                {
                    Projectile.velocity *= 1.03f;
                }
                Projectile projectile = Projectile;
                projectile.velocity.Y = projectile.velocity.Y + forceGravity * 0.025f;
                forceGravity += MathHelper.Clamp(forceGravity, Projectile.velocity.Y / 1500f, 0.04f);
                Projectile.rotation = Projectile.velocity.ToRotation() + 0.7853982f;
                Vector2 position = Projectile.Center + Projectile.velocity * 3.5f;
                Vector2 velocity = (-Projectile.velocity * Main.rand.NextFloat(0.2f, 0.35f)).RotatedByRandom(0.6981317400932312);
                if (Main.rand.NextBool(3))
                {
                    MyUtils.CreateDust(DustID.TerraBlade, velocity, position, Color.White, Main.rand.NextFloat(0.8f, 1.5f), 0, false, true);
                }
            }
        }
        private void HeldAI()
        {
            int SwingMaxDuration = Owner.itemAnimationMax;
            Owner.heldProj = Projectile.whoAmI;
            if (Projectile.timeLeft > SwingMaxDuration)
            {
                Projectile.timeLeft = SwingMaxDuration;
            }
            Projectile.velocity = Vector2.Normalize(Projectile.velocity);
            float HalfDuration = SwingMaxDuration * 0.5f;
            if (Projectile.timeLeft < HalfDuration)
            {
                Time = Projectile.timeLeft / HalfDuration;
            }
            else
            {
                Time = (SwingMaxDuration - Projectile.timeLeft) / HalfDuration;
            }
            Projectile.Center = Owner.MountedCenter + Vector2.SmoothStep(Projectile.velocity * 8f, Projectile.velocity * 40f, Time);
            int spriteDirection = Projectile.spriteDirection;
            Projectile.rotation = Projectile.velocity.ToRotation() + 0.7853982f;
            Projectile.velocity = Projectile.velocity.RotatedBy((double)MathHelper.ToRadians(Time), default);
            Owner.SetCompositeArmFront(true, 0, (Projectile.velocity * 2f).RotatedBy(4.71238899230957, default).ToRotation());
        }
        private bool CheckCurrentAmountStuckInNPC(NPC n)
        {
            int amount = 0;
            foreach (Projectile p in Main.ActiveProjectiles)
            {
                if (p.type == Projectile.type && p.active && p.owner == Projectile.owner)
                {
                    Miasma proj = p.ModProjectile as Miasma;
                    if (proj != null && proj.StuckIndex == n.whoAmI)
                    {
                        amount++;
                    }
                }
            }
            return amount <= 4;
        }
        public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone)
        {
            if (Mode == 1f && !StuckInSomething[0] && !StuckInSomething[1])
            {
                if (CheckCurrentAmountStuckInNPC(target))
                {
                    StuckIndex = target.whoAmI;
                    Projectile.velocity = (target.Center - Projectile.Center) * 0.725f;
                    Projectile.netUpdate = true;
                    StuckInSomething[0] = true;
                    if (Main.rand.NextFloat() < 0.08)
                    {
                        target.AddBuff(ModContent.BuffType<Corrosion>(), 120, false);
                    }
                    return;
                }
                Projectile.Kill();
            }
        }
        public override bool OnTileCollide(Vector2 oldVelocity)
        {
            if (Mode == 1f && !StuckInSomething[0])
            {
                Projectile.velocity *= 0f;
                Collision.HitTiles(Projectile.Center + Projectile.velocity * 3f, Projectile.velocity, 10, 10);
                StuckInSomething[1] = true;
            }
            return false;
        }
        public override void ModifyDamageHitbox(ref Rectangle hitbox)
        {
            if (Mode == 1f)
            {
                hitbox.Inflate(-20, -20);
            }
            base.ModifyDamageHitbox(ref hitbox);
        }
        public override bool TileCollideStyle(ref int width, ref int height, ref bool fallThrough, ref Vector2 hitboxCenterFrac)
        {
            width = height = 4;
            return base.TileCollideStyle(ref width, ref height, ref fallThrough, ref hitboxCenterFrac);
        }
        public override bool PreDraw(ref Color lightColor)
        {
            if (tex == null)
            {
                tex = ModContent.Request<Texture2D>(Texture, (ReLogic.Content.AssetRequestMode)2).Value;
            }
            Projectile.SimpleDrawProjectile(tex, lightColor, false, 1f, 0f);
            if (Mode == 1f && !StuckInSomething[0])
            {
                bool flag = StuckInSomething[1];
            }
            return false;
        }

    }
}

